package com.eonmind.vip.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.eonmind.common.contract.data.response.PageResponse;
import com.eonmind.common.contract.enums.vip.ConsumptionTypeEnum;
import com.eonmind.common.contract.timer.Timer;
import com.eonmind.common.provider.entity.vip.PointsConsumption;
import com.eonmind.user.contract.dto.UserInfoData;
import com.eonmind.vip.dto.ConsumptionDto;
import com.eonmind.vip.mapper.PointsMapper;
import com.eonmind.vip.mapper.UserWelfareMapper;
import com.eonmind.vip.provider.VipToUserServerProvider;
import com.eonmind.vip.service.PointsService;
import com.eonmind.vip.util.TimeUtil;
import com.mongoplus.model.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.*;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class PointsServiceImpl implements PointsService {

    @Autowired
    private PointsMapper pointsMapper;

    @Autowired
    private UserWelfareMapper userWelfareMapper;

    @Autowired
    private VipToUserServerProvider vipToUserServerProvider;


    @Override
    public void savePointsConsumption(PointsConsumption pointsConsumption, UserInfoData userInfoData) {
        if (ObjectUtil.isEmpty(pointsConsumption.getUserID())) {
            pointsConsumption.setUserID(userInfoData.getId());
        }
        if (ObjectUtil.isEmpty(pointsConsumption.getBalance())) {

            pointsConsumption.setBalance(userWelfareMapper.getUserPlanByUserID(userInfoData.getId()).getCachedFeatures().getTotalCoins());
        }
        pointsConsumption.setCreateTime(Timer.currentTimestamp())
                        .setUpdateTime(Timer.currentTimestamp());
        pointsMapper.save(pointsConsumption);
    }


    @Override
    public PageResponse<ConsumptionDto.ConsumptionResponse> getAllConsumption(UserInfoData userInfoData, ConsumptionDto.ConsumptionPageRequest pageRequest) {
        PageResponse<ConsumptionDto.ConsumptionResponse> pageResponse = new PageResponse<>();
        if (ObjectUtil.isEmpty(pageRequest) || ObjectUtil.isEmpty(pageRequest.getPage()) || ObjectUtil.isEmpty(userInfoData)) {
            return pageResponse;
        }

        PageResult<PointsConsumption> page = pointsMapper.page(userInfoData, pageRequest);
        List<ConsumptionDto.ConsumptionResponse> list = page.getContentData().stream().map(
                item -> new ConsumptionDto.ConsumptionResponse()
                        .setDate(TimeUtil.LongToString(item.getCreateTime()))
                        .setType(item.getCategory())
                        .setPointsChange(item.getConsumption())
                        .setModelName(item.getModelName())
                        .setDescription(item.getDescription())
                        .setBalance(item.getBalance())
                        .setCategory(ConsumptionTypeEnum.getDescByCode(item.getType()))
        ).toList();
        pageResponse.setValue(pageRequest.getPage(), page.getTotalSize(), list);
        return pageResponse;
    }

    @Override
    public List<ConsumptionDto.MonthConsumption> getMonthConsumption(UserInfoData userInfoData) {
        LocalDate currentDate = LocalDate.now();
        Long userId = userInfoData.getId();
        ArrayList<ConsumptionDto.MonthConsumption> monthConsumptions = new ArrayList<>();
        for (int i = 0; i <= 4; i++) {
            LocalDate minusedMonths = currentDate.minusMonths(i);
            String date = minusedMonths.getYear() + "-" + minusedMonths.getMonthValue();
            long startTime = convertToTimestamp(minusedMonths.with(TemporalAdjusters.firstDayOfMonth()).atStartOfDay());
            long endTime = convertToTimestamp(minusedMonths.with(TemporalAdjusters.lastDayOfMonth()).atTime(LocalTime.MAX));
            Integer income = pointsMapper.gePointsByMonth(userId, startTime, endTime, "获取");
            Integer outcome = pointsMapper.gePointsByMonth(userId, startTime, endTime, "使用");
            ConsumptionDto.MonthConsumption monthConsumption = new ConsumptionDto.MonthConsumption().setDate(date).setIncome(income).setOutcome(outcome);
            monthConsumptions.add(monthConsumption);
        }
        return monthConsumptions;
    }

    public static long convertToTimestamp(LocalDateTime localDateTime) {
        // 将LocalDateTime转换为ZonedDateTime，这里使用系统默认时区
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());

        // 将ZonedDateTime转换为Instant
        Instant instant = zonedDateTime.toInstant();

        // 获取时间戳（毫秒）
        return instant.toEpochMilli();
    }
}
